home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr46 / vfwdk.zip / VFWSDK.ZIP / SAMPLES / BRAVADO / CTDEV.C < prev    next >
C/C++ Source or Header  |  1993-01-31  |  15KB  |  571 lines

  1. /****************************************************************************
  2.  *
  3.  *   ctdev.c
  4.  * 
  5.  *   Hardware specific routines.  
  6.  *
  7.  *   Microsoft Video for Windows Sample Capture Driver
  8.  *   Chips & Technologies 9001 based frame grabbers.
  9.  *
  10.  *   Copyright (c) 1992-1993 Microsoft Corporation.  All Rights Reserved.
  11.  *
  12.  *    You have a royalty-free right to use, modify, reproduce and 
  13.  *    distribute the Sample Files (and/or any modified version) in 
  14.  *    any way you find useful, provided that you agree that 
  15.  *    Microsoft has no warranty obligations or liability for any 
  16.  *    Sample Application Files which are modified. 
  17.  *
  18.  ***************************************************************************/
  19.  
  20. #include <windows.h>
  21. #include <mmsystem.h>
  22. #include <conio.h>
  23. #include <msvideo.h>
  24. #include <msviddrv.h>
  25. #include "ct.h"         // General include
  26. #include "ctdev.h"      // Device specific include
  27. #include "debug.h"      
  28.  
  29. #ifdef _VBLASTER
  30. #include "pcvideo.h"
  31. char gszDriverName[]              = "VBlaster.drv";
  32. #endif
  33.  
  34. #ifdef _BRAVADO
  35. #include "vwproto.h"
  36. VWCFG VWConfigBuf;
  37. char gszDriverName[]              = "Bravado.drv";
  38. #endif
  39.  
  40. #define KEY_COLOR_INDEX  5
  41.  
  42. WORD FAR PASCAL GetProfileHex(LPSTR szApp, LPSTR szEntry, WORD wDef);
  43.  
  44. static HBRUSH   hOverlayBrush;      // Overlay brush used to paint window
  45. static RECT     rcLastScreen;       // Last screen coords of overlay window
  46. static BOOL     fOverlayEnabled;    // Is overlay showing?
  47.  
  48. /*======================================================== 
  49.              Low level read/write routines               
  50. =========================================================*/
  51.  
  52. // Write a byte to a PCVideo Chip register
  53. void FAR PASCAL CT_WritePCVideo (int nIndex, int nValue)
  54. {
  55.     outp (wPCVideoAddress, nIndex);
  56.     outp (wPCVideoAddress + 1, nValue);
  57. }
  58.  
  59. // Read a byte from a PC Video chip register
  60. int FAR PASCAL CT_ReadPCVideo (int nIndex)
  61. {
  62.     outp (wPCVideoAddress, nIndex);
  63.     return (inp (wPCVideoAddress + 1));
  64. }
  65.  
  66.  
  67. /*======================================================== 
  68.              Initialization and Fini
  69. =========================================================*/
  70.  
  71. // Initialization routine called only once at driver load time.
  72. // Returns TRUE on success
  73. BOOL FAR PASCAL CT_Init ()
  74. {
  75.     WORD wRet;
  76.     WORD wLuma;
  77.  
  78. #pragma message("Try reducing luma bandwidth!!!")
  79.     wLuma = GetProfileHex(gszDriverName, "9051Reg6", 0x6c );
  80.  
  81. #ifdef _BRAVADO
  82.     VW_SetConfigBuf (&VWConfigBuf);
  83.     VW_SetDefaultConfiguration (0);
  84.     CT_SetPortAddress (wPCVideoAddress); 
  85.  
  86.     wRet = (VW_Init (0) == 1);  // returns 1 on success
  87.     VW_Set9051Reg (6, wLuma);    // Lower luma bandwidth to reduce noise!!!
  88. #endif
  89.  
  90. #ifdef _VBLASTER
  91.     wRet = vbcInitialize (); 
  92.     vbcSetRegister (0x8a06, (BYTE) wLuma);
  93. #endif
  94.  
  95.     if (wRet) {
  96.         wPCVideoAddress = CT_GetPortAddress ();
  97.  
  98.         // Create the overlay brush
  99.         hOverlayBrush = CT_SetKeyColor ();
  100.         CT_OverlayEnable (FALSE);   // Initially disable the overlay
  101.         CT_Acquire (FALSE);         // Turn off acquisition so we can test memory
  102.     }
  103.     return wRet;
  104. }
  105.  
  106. // Called during shutdown of the driver.
  107. void FAR PASCAL CT_Fini ()
  108. {
  109.     if (hOverlayBrush) {
  110.         DeleteObject (hOverlayBrush);
  111.         hOverlayBrush = NULL;
  112.     }
  113.  
  114. #ifdef _BRAVADO
  115.     VW_CleanUp ();
  116. #endif
  117.  
  118. #ifdef _VBLASTER
  119.     vbcExit (); 
  120. #endif
  121. }
  122.  
  123. /*======================================================== 
  124.                 Ports and addresses
  125. =========================================================*/
  126.  
  127. // Set the Base I/O port used by the device
  128. void FAR PASCAL CT_SetPortAddress (int nPort)
  129. {
  130. #ifdef _BRAVADO
  131.     VW_SetIOAddr (nPort);
  132. #endif
  133.  
  134. #ifdef _VBLASTER
  135.     PCV_SetPortAddress (nPort);   // This doesn't work!!!
  136. #endif
  137.  
  138.     wPCVideoAddress = CT_GetPortAddress ();
  139. }
  140.  
  141. // Get the Base I/O port used by the device
  142. int FAR PASCAL CT_GetPortAddress ()
  143. {
  144. #ifdef _BRAVADO
  145.     return VW_GetIOAddr ();
  146. #endif
  147.  
  148. #ifdef _VBLASTER
  149.     // VBlaster uses the address set in the Creative Labs setup app.
  150.     return vbcGetPortAddress ();
  151. #endif
  152. }
  153.  
  154. // Get Linear memory address of frame buffer
  155. // Returns value in the range 1 to 15 (meg)
  156. int FAR PASCAL CT_GetFrameAddress ()
  157. {
  158. #ifdef _BRAVADO
  159.     return VW_GetVidAddr ();
  160. #endif
  161.  
  162. #ifdef _VBLASTER
  163.     return vbcGetVideoAddress ();
  164. #endif
  165. }
  166.  
  167. // Set Linear memory address of frame buffer
  168. // nVidAddr is linear address div. 0x100000 (ie. 1-15)
  169. int FAR PASCAL CT_SetFrameAddress (int nVidAddr)
  170. {
  171. #ifdef _BRAVADO
  172.     return VW_SetVidAddr (nVidAddr);
  173. #endif
  174.  
  175. #ifdef _VBLASTER
  176.     return vbcSetVideoAddress (nVidAddr);
  177. #endif
  178. }
  179.  
  180. /*======================================================== 
  181.                     Configuration
  182. =========================================================*/
  183.  
  184. // Load configuration from a file.
  185. // Returns TRUE on success, FALSE on failure
  186. BOOL FAR PASCAL CT_LoadConfiguration (LPSTR lpszFile)
  187. {
  188. #ifdef _BRAVADO
  189.     return (VW_LoadConfiguration (lpszFile));
  190. #endif
  191.  
  192. #ifdef _VBLASTER
  193.     return vbcLoadConfiguration ();     // Does not support file name!!!
  194. #endif
  195. }
  196.  
  197. // Save configuration to a file.
  198. // Returns TRUE on success, FALSE on failure
  199. BOOL FAR PASCAL CT_SaveConfiguration (LPSTR lpszFile)
  200. {
  201. #ifdef _BRAVADO
  202.     return (VW_SaveConfiguration (lpszFile));
  203. #endif
  204.  
  205. #ifdef _VBLASTER
  206.     return vbcSaveConfiguration ();     // Does not support file name!!!
  207. #endif
  208. }
  209.  
  210. // Set the video source
  211. // nSource ranges from 0 to ...
  212. void FAR PASCAL CT_SetVideoSource (int nSource)
  213. {
  214. #ifdef _BRAVADO
  215.     VW_SetVidSource (nSource);
  216. #endif
  217.  
  218. #ifdef _VBLASTER
  219.     vbcSetVideoSource ((WORD) nSource);
  220. #endif
  221. }
  222.  
  223. // Get the number of video input channels available.
  224. int FAR PASCAL CT_GetVideoChannelCount (void)
  225. {
  226. #ifdef _BRAVADO
  227.     return 3;   // Some cables only have 1 input, but always allow 3
  228. #endif
  229.  
  230. #ifdef _VBLASTER
  231.     return 3;
  232. #endif
  233. }
  234.  
  235. // Set the video standard
  236. // 0 = NTSC, 1 = PAL
  237. void FAR PASCAL CT_SetVideoStandard (int nStandard)
  238. {
  239. #ifdef _BRAVADO
  240.     VW_SetVidStandard (nStandard == 0 ? 1 : 0);
  241. #endif
  242.  
  243. #ifdef _VBLASTER
  244.    vbcSetInputFormat (nStandard == 0 ? CF_NTSC : CF_PAL);
  245. #endif
  246. }
  247.  
  248. // Return TRUE if the device can accept SVideo
  249. BOOL FAR PASCAL CT_HasSVideo ()
  250. {
  251. #ifdef _BRAVADO
  252.     return TRUE;
  253. #endif
  254.  
  255. #ifdef _VBLASTER
  256.    return FALSE;
  257. #endif
  258. }
  259.  
  260. // Set the selected input channel format to:
  261. // 0 = composite
  262. // 1 = SVideo
  263. // 2 = RGB (someday?)
  264.  
  265. BOOL FAR PASCAL CT_SetVideoCableFormat (int nInputMode)
  266. {
  267. #ifdef _BRAVADO
  268.     VW_SetSVid (nInputMode);
  269.     return TRUE;
  270. #endif
  271.  
  272. #ifdef _VBLASTER
  273.     return FALSE;       // Can't do SVideo
  274. #endif
  275. }
  276.  
  277. // Set the Color control registers 
  278. // nVal on input ranges from 0 to 0x3f
  279. void FAR PASCAL CT_SetColor(int nReg, int nVal)
  280. {
  281. #ifdef _BRAVADO
  282.     // All Bravado values EXCEPT hue range 0-0x3f, hue goes from 0-0xff
  283.     if (nReg == 0)
  284.         nVal *= 4;      
  285.     VW_SetColor (nReg, nVal);
  286. #endif
  287.  
  288. #ifdef _VBLASTER
  289.     // All Video Blaster color values range 0-0xff
  290.     nVal *= 4; 
  291.     switch (nReg) {
  292.         case CT_COLOR_HUE:          nReg = 3; break;
  293.         case CT_COLOR_BRIGHTNESS:   nReg = 0; break;
  294.         case CT_COLOR_SAT:          nReg = 1; break;
  295.         case CT_COLOR_CONTRAST:     nReg = 2; break;
  296.     }
  297.     vbcSetColor (nReg, (BYTE) nVal);
  298. #endif
  299. }
  300.  
  301.  
  302. /*======================================================== 
  303.                     Rectangles
  304. =========================================================*/
  305.  
  306. // Create and Position the overlay window
  307. void FAR PASCAL CT_SetDisplayRect (LPRECT lpRectangle)
  308. {
  309.     RECT rR = *lpRectangle;
  310.  
  311.     OffsetRect (&rR, rcLastScreen.left, rcLastScreen.top);
  312.  
  313. #ifdef _BRAVADO
  314.     VW_SetVidWindow (rR.left, rR.top, WidthRect(rR), HeightRect(rR), 1);
  315. #endif
  316.  
  317. #ifdef _VBLASTER
  318.     vbcCreateWindow (rR.left, rR.top, WidthRect(rR), HeightRect(rR), 1);
  319. #endif
  320. }
  321.  
  322. void FAR PASCAL CT_SetPanAndScroll (LPRECT lpRectangle)
  323. {
  324.     RECT rR = *lpRectangle;
  325. #ifdef _BRAVADO
  326.     VW_SetVidPan (rR.left, rR.top);
  327. #endif
  328.  
  329. #ifdef _VBLASTER
  330.     vbcPanWindow (rR.left, rR.top);
  331. #endif
  332.         
  333. }
  334.  
  335. /*======================================================== 
  336.             Overlay keying and Painting
  337. =========================================================*/
  338.  
  339. // Set the overlay key color
  340. // Returns a brush which is used to paint the key color
  341. HBRUSH FAR PASCAL CT_SetKeyColor ()
  342. {
  343. #ifdef _BRAVADO
  344.     {
  345.         HWND hWnd;
  346.         HDC  hDC;
  347.         int  iColors;
  348.  
  349.         hWnd = GetDesktopWindow ();
  350.         hDC  = GetDC (hWnd);
  351.         iColors = GetDeviceCaps (hDC, NUMCOLORS);
  352.         ReleaseDC (hWnd, hDC);
  353.  
  354.         // Bravado16 only uses high byte for key, so create a special brush
  355.         if (iColors > 256) {
  356.             COLORREF cref = RGB (0x7f, 0, 0x7f);
  357.  
  358.             VW_SetRGBKeyColor (cref);
  359.             return  (CreateSolidBrush (cref));
  360.         }
  361.         else {
  362.             VW_SetKeyColor (KEY_COLOR_INDEX);
  363.             return  (CreateSolidBrush (PALETTEINDEX (KEY_COLOR_INDEX)));
  364.         }
  365.         hDC  = GetDC (hWnd);
  366.     }
  367. #endif
  368.  
  369. #ifdef _VBLASTER
  370.     vbcSetColorKey ((WORD) KEY_COLOR_INDEX);
  371.     return  (CreateSolidBrush (PALETTEINDEX (KEY_COLOR_INDEX)));
  372. #endif
  373. }
  374.  
  375. // Turn overlay display on or off
  376. void FAR PASCAL CT_OverlayEnable (BOOL fDisplay)
  377. {
  378.     fOverlayEnabled = fDisplay;
  379.  
  380. #ifdef _BRAVADO
  381.     VW_SetVidShow (fDisplay);
  382. #endif
  383.  
  384. #ifdef _VBLASTER
  385.     if (fDisplay)
  386.         vbcEnableVideo ();
  387.     else
  388.         vbcDisableVideo ();
  389. #endif
  390. }
  391.  
  392.  
  393. // Update the overlay window rectangle and paint the key color
  394. void FAR PASCAL CT_Update (HWND hWnd, HDC hDC)
  395. {
  396.     RECT rcScreen, rcClient;
  397.     HBRUSH hbrOld;
  398.  
  399.     rcScreen = grcDestExtOut;
  400.     rcScreen.right = rcScreen.left + gwWidth -1;
  401.     rcScreen.bottom = rcScreen.top + gwHeight -1;
  402.  
  403. #ifdef _BRAVADO
  404.     if (!EqualRect (&rcScreen, &rcLastScreen)) {
  405.         VW_SetVidWindow (rcScreen.left, rcScreen.top, 
  406.                 WidthRect(rcScreen), HeightRect(rcScreen), 1);
  407.     }
  408. #endif
  409.  
  410. #ifdef _VBLASTER
  411.     if (!EqualRect (&rcScreen, &rcLastScreen)) {
  412.         vbcSetWindowPosition (rcScreen.left, rcScreen.top);
  413.         vbcSetWindowSize (WidthRect(rcScreen), HeightRect(rcScreen), 1);
  414.     }
  415. #endif
  416.  
  417.     CT_SetPanAndScroll (&grcSourceExtOut);
  418.  
  419.     // Paint the key color into grcDestExtOut (which is in screen coords)
  420.     rcClient = grcDestExtOut;
  421.     ScreenToClient (hWnd, (LPPOINT) &rcClient);
  422.     ScreenToClient (hWnd, (LPPOINT) &rcClient+1);
  423.     hbrOld = SelectObject (hDC, hOverlayBrush);
  424.     PatBlt (hDC, rcClient.left, rcClient.top, 
  425.             rcClient.right - rcClient.left, 
  426.             rcClient.bottom - rcClient.top, 
  427.             PATCOPY);
  428.     SelectObject (hDC, hbrOld);
  429.  
  430.     rcLastScreen = rcScreen;
  431. }
  432.  
  433. /*======================================================== 
  434.             Image acquistion and grabbing
  435. =========================================================*/
  436.  
  437. // Turn acquisition of images into frame buffer on or off
  438. // Not interrupt callable, since it enters the client DLL.
  439. void FAR PASCAL CT_Acquire (BOOL fAcquire)
  440. {
  441. #ifdef _BRAVADO
  442.     VW_SetFreezeVid (fAcquire ? 0 : 1); // Backwards
  443. #endif
  444.  
  445. #ifdef _VBLASTER
  446.     if (fAcquire)
  447.         vbcUnFreezeVideo ();
  448.     else
  449.         vbcFreezeVideo ();
  450. #endif
  451.     
  452. }
  453.  
  454. // This routine is interrupt callable, and bypasses
  455. // the client DLL.
  456. void FAR PASCAL CT_PrivateAcquire (BOOL fAcquire)
  457. {
  458.     CT_WritePCVideo (0x20, ((CT_ReadPCVideo (0x20) & 0xfe) 
  459.         | (fAcquire ? 1 : 0)));
  460.  
  461.     // On a FREEZE, wait for acquisition to complete
  462.     // otherwise PCVIDEO asserts the READY line for 20mS.
  463.     // when the first video memory read occurs!!!
  464.     // This behavior violates PC bus specs.
  465.     if (!fAcquire)
  466.         while (CT_ReadPCVideo (0x20) & 1);
  467. }
  468.  
  469.  
  470. // Capture a single frame
  471. // Return frozen
  472. void FAR PASCAL CT_GrabFrame (void)
  473. {
  474.     CT_Acquire (TRUE);
  475.     CT_WaitVSync (0);    // Wait Even
  476.     CT_WaitVSync (1);    // Wait Odd
  477.     CT_Acquire (FALSE);
  478. }
  479. /*======================================================== 
  480.               Interrupts and Sync
  481. =========================================================*/
  482. // Set the IRQ used by the device.
  483. // Returns the IRQ actually set.
  484. int FAR PASCAL CT_SetIRQUsed (int nIRQ)
  485. {
  486.  
  487. #ifdef _BRAVADO
  488.     return 9;          // only 9 is available from this card
  489. #endif
  490.  
  491. #ifdef _VBLASTER
  492.     {
  493.         int nTemp;
  494.         switch (nIRQ) {
  495.            case 5:  nTemp = 1; break;
  496.            case 10: nTemp = 2; break;
  497.            case 11: nTemp = 4; break;
  498.            case 12: nTemp = 8; break;
  499.            default: return (CT_GetIRQUsed ()); // illegal value, return default
  500.         }
  501.         CT_WritePCVideo (0x82, nTemp);
  502.         return nIRQ;
  503.     }
  504. #endif
  505. }
  506.  
  507. // Returns the IRQ used by the device
  508. int FAR PASCAL CT_GetIRQUsed ()
  509. {
  510. #ifdef _BRAVADO
  511.     return 9;          // only 9 is available from this card
  512. #endif
  513.  
  514. #ifdef _VBLASTER
  515.     return vbcGetIntrNo();
  516. #endif
  517. }
  518.  
  519. #define EVEN_VSYNC_INTERRUPT 0x01
  520. #define  ODD_VSYNC_INTERRUPT 0x02
  521.  
  522. // Enable the PCVideo chip to create odd and even interrupts
  523. void FAR PASCAL CT_IRQEnable (void)
  524. {
  525. #if FRAME_INTERRUPT
  526.     CT_WritePCVideo (0x09, EVEN_VSYNC_INTERRUPT);
  527. #else
  528.     CT_WritePCVideo (0x09, EVEN_VSYNC_INTERRUPT | ODD_VSYNC_INTERRUPT);
  529. #endif
  530. }
  531.  
  532. void FAR PASCAL CT_IRQDisable (void)
  533. {
  534.     CT_WritePCVideo (0x09, 0);         // Disable Interrupts
  535. }
  536.  
  537. // Clear PCVideo chip interrupts
  538. void FAR PASCAL CT_IRQClear (void)
  539. {
  540.     CT_WritePCVideo (0x09, 0);         // Clear the interrupt
  541.  
  542. #if FRAME_INTERRUPT
  543.     CT_WritePCVideo (0x09, EVEN_VSYNC_INTERRUPT);  // Re-enable it
  544. #else
  545.     CT_WritePCVideo (0x09, ODD_VSYNC_INTERRUPT | EVEN_VSYNC_INTERRUPT);  // Re-enable it
  546. #endif
  547. }
  548.  
  549.  
  550. // Wait for Vertical Sync
  551. // nSync = 0, wait even
  552. // nSync = 1, wait odd
  553. // nSync = 2, wait either
  554. void FAR PASCAL CT_WaitVSync (int nSync)
  555. {
  556.     WORD  wRegVal;
  557.     BOOL  bOdd;
  558.     DWORD dwStartTime = timeGetTime();
  559.     
  560.     while (timeGetTime () - dwStartTime < 33) {
  561.         wRegVal = CT_ReadPCVideo (9);
  562.         bOdd = wRegVal & 0x08;
  563.         if (wRegVal & 0x04) {        // if VSync
  564.            if ((nSync == 2) || 
  565.               ((nSync == 1) && bOdd) ||
  566.               ((nSync == 0) && !bOdd))
  567.               break;
  568.         }
  569.     }
  570. }
  571.